//||=========================================================================||
//||                                                                         |
//||                             MainWindow.cpp                              ||
//||                                                                         ||
//||                           by the_best_goose))                           ||
//||                                                                         ||
//||=========================================================================||

#include <QtGui>
#include <assert.h>
#include "MainWindow.h"
#include "MandelbrotWgt.h"
#include "MandelbrotCounter.h"

//-----------------------------------------------------------------------------

MainWindow::MainWindow(MandelbrotWgtMaker pmand, QWidget* pwgt):
QMainWindow(pwgt),
file_menu_(NULL),
help_menu_(NULL),
view_menu_(NULL),
exit_act_(NULL),
about_act_(NULL),
about_qt_act_(NULL),
create_julia_act_(NULL),
set_mapping_act_(NULL),
set_t_re_act_(NULL),
set_t_im_act_(NULL),
pmandelbrot_(NULL),
pjulia_wind_(NULL),
mapping_("t * Z^3 + (1 - t) * Z^2 + C"),
t_re_(0.0f),
t_im_(0.0f),
iters_count_(500)
{
	assert(pmand);
	pmandelbrot_ = pmand(this);
    CreateActions();
    CreateMenus();
    setWindowTitle(tr("TBG-Fractal"));
    setCentralWidget(pmandelbrot_);
    emit TReChanged(t_re_, false);
    emit TImChanged(t_im_, false);
    emit MappingChanged(mapping_.toStdString());
    emit IterationsCountChanged(iters_count_);
}

//-----------------------------------------------------------------------------

MainWindow::~MainWindow ()
{
	assert(pmandelbrot_);
	delete pmandelbrot_;
    emit Deleted();
}

//-----------------------------------------------------------------------------

void MainWindow::About()
{
    QMessageBox::about(this, tr("About TBG-Fractal"),
                       tr ("The <b>TBG-Fractal</b> creates the universal \
                            Mandelbrot set and julia set for different \
                            complex functions. It was written by Oleg \
                            Ponomarev <the_best_goose@mail.ru>"));
}

//-----------------------------------------------------------------------------

void MainWindow::SetMapping()
{
    bool ok = false;
        int error_ans = QMessageBox::Cancel;
    for(;;)
    {
        mapping_ = QInputDialog::getText(this, tr("TBG-Fractal settings"),
                                         tr("Enter mapping:"),
                                         QLineEdit::Normal,
                                         mapping_, &ok);
        if(!ok)
        	return;
        else if(MandelbrotCounter::IsValid(mapping_.toStdString()))
        	break;
    	error_ans = QMessageBox::critical(this, "TBG-Fractal error",
    		       	                      "Invalid mapping formula! Check it \
    		       	                       for errors!",
    			                          QMessageBox::Cancel,
    			                          QMessageBox::Retry);

        if(error_ans == QMessageBox::Cancel)
        	return;
    }

    emit MappingChanged(mapping_.toStdString());
}

//-----------------------------------------------------------------------------

void MainWindow::SetJuliaPointer(QPointF point)
{
point = point;
}

//-----------------------------------------------------------------------------

void MainWindow::SetItersCount()
{
    bool ok = false;
    iters_count_ = QInputDialog::getInt(this, tr("TBG-Fractal settings"),
                                        tr("Select iterations count:"),
                                        iters_count_, 1, 1000000, 1, &ok);
    if(!ok)
    	return;
//    QVector<IMandelbrotCounter*> counters = pmandelbrot_->GetCounter();
    emit IterationsCountChanged(iters_count_);
}

//-----------------------------------------------------------------------------

void MainWindow::SetTRe()
{
    bool ok = false;
    t_re_ = QInputDialog::getDouble(this, tr("TBG-Fractal settings"),
                                    tr("Set real part of T parameter:"), t_re_,
                                    -10000, 10000, 10, &ok);
    if(!ok)
    	return;
    emit TReChanged(t_re_);
}

//-----------------------------------------------------------------------------

void MainWindow::SetTIm ( )
{
    bool ok = false;
    t_im_ = QInputDialog::getDouble(this, tr("TBG-Fractal settings"),
                                    tr("Set imagine part of T parameter:"),
                                    t_im_, -10000, 10000, 10, &ok);
    if(!ok)
    	return;
    emit TImChanged(t_im_);
}

//-----------------------------------------------------------------------------
/*
void MainWindow::CreateJulia ( )
    {
    assert ( pmandelbrot_ );
    if ( pjulia_wind_ )
        {
        create_julia_act_->setChecked ( false );
        assert ( pjulia_wind_ );
        delete pjulia_wind_;
        pjulia_wind_ = NULL;
        pmandelbrot_->DisableJuliaPointer ( );
        return;
        }

    assert ( pjulia_wind_ == NULL );
    SimpleJuliaCounter* pjulia_counter = new SimpleJuliaCounter ( c_ );
    MandelbrotWgt* pjulia = new MandelbrotWgt ( pjulia_counter );
    pjulia_wind_ = new MainWindow ( false, pjulia, this );
    pjulia_wind_->setWindowTitle ( "Julia set" );
    pjulia_wind_->show ( );
    create_julia_act_->setChecked ( true );
    connect ( pjulia_wind_, SIGNAL ( Deleted ( ) ), this, SLOT ( JuliaKilled ( ) ) );
    pmandelbrot_->EnableJuliaPointer ( );
    connect ( pmandelbrot_, SIGNAL ( JuliaPointerChanged ( QPointF ) ), pjulia_counter, SLOT ( SetC ( QPointF ) ) );
    pmandelbrot_->Recount ( );
    }

//-----------------------------------------------------------------------------

void MainWindow::JuliaKilled ( )
    {
    assert ( pmandelbrot_ );
    pjulia_wind_ = NULL;
    pmandelbrot_->DisableJuliaPointer ( );
    create_julia_act_->setChecked ( false );
    }
*/
//-----------------------------------------------------------------------------

void MainWindow::CreateActions()
{
    exit_act_ = new QAction(tr("E&xit"), this);
    exit_act_->setShortcut(tr("Ctrl+Q"));
    exit_act_->setStatusTip (tr("Exit the application"));
    connect(exit_act_, SIGNAL(triggered()), this, SLOT(close()));

    about_act_ = new QAction(tr("&About"), this);
    about_act_->setStatusTip(tr("Show the application's About box"));
    connect(about_act_, SIGNAL(triggered()), this, SLOT(About()));

    about_qt_act_ = new QAction(tr("About &Qt"), this);
    about_qt_act_->setStatusTip(tr("Show the Qt library's About box"));
    connect(about_qt_act_, SIGNAL(triggered()), qApp, SLOT(aboutQt()));

/*    create_julia_act_ = new QAction(tr("Show &Julia"), this);
    create_julia_act_->setShortcut(tr("Ctrl+J"));
    create_julia_act_->setStatusTip("Show the Julia set for current constant");
    create_julia_act_->setCheckable(true);
    create_julia_act_->setChecked(false);
    connect(create_julia_act_, SIGNAL(triggered()), this, SLOT(CreateJulia()));
*/
    set_iters_count_act_ = new QAction(tr("Set &Iterations Count"), this);
    set_iters_count_act_->setShortcut(tr("Ctrl+I"));
    set_iters_count_act_->setStatusTip(
    		                    tr("Set precision of counting Mandelbrot set"));
    connect(set_iters_count_act_, SIGNAL(triggered()), this,
    		SLOT(SetItersCount()));

    set_t_re_act_ = new QAction(tr("&Real part of 't'"), this);
    set_t_re_act_->setShortcut(tr("Ctrl+R"));
    set_t_re_act_->setStatusTip(tr("Set real part of parameter \'t\'"));
    connect(set_t_re_act_, SIGNAL(triggered()), this, SLOT(SetTRe()));

    set_t_im_act_ = new QAction(tr("&Complex complex of 't'"), this);
    set_t_im_act_->setShortcut(tr("Ctrl+C"));
    set_t_im_act_->setStatusTip(tr("Set complex part of parameter \'t\'"));
    connect(set_t_im_act_, SIGNAL(triggered()), this, SLOT(SetTIm()));

    set_mapping_act_ = new QAction(tr("Set &Mapping"), this);
    set_mapping_act_->setShortcut(tr("Ctrl+M"));
    set_mapping_act_->setStatusTip(tr("Set mapping for Mandelbrot"));
    connect(set_mapping_act_, SIGNAL(triggered()), this, SLOT(SetMapping()));
}

//-----------------------------------------------------------------------------

void MainWindow::CreateMenus()
{
    file_menu_ = menuBar()->addMenu(tr("&File"));
    file_menu_->addAction(exit_act_);

/*    view_menu_ = menuBar()->addMenu(tr("&View"));
    view_menu_->addAction(create_julia_act_);
*/
    mandelbrot_menu_ = menuBar()->addMenu(tr("&Mandelbrot"));
    mandelbrot_menu_->addAction(set_iters_count_act_);
    mandelbrot_menu_->addAction(set_mapping_act_);
    mandelbrot_menu_->addAction(set_t_re_act_);
    mandelbrot_menu_->addAction(set_t_im_act_);

    help_menu_ = menuBar()->addMenu(tr("&Help"));
    help_menu_->addAction(about_act_   );
    help_menu_->addAction(about_qt_act_);

}
